home *** CD-ROM | disk | FTP | other *** search
- #import "../3Dincludes.h"
- #import "Sphere.h"
- @implementation Sphere
-
- static int shapeNumber = 1;
- - (int)shapeNumber
- {
- return shapeNumber++;
- }
-
- - calcBoundingBox
- {
- // xmin & xmax
- boundingBox[0]=-radius;
- boundingBox[1]=radius;
-
- // ymin & ymax
- boundingBox[2]=-radius;
- boundingBox[3]=radius;
-
- // zmin & zmax
- boundingBox[4]=zMin;
- boundingBox[5]=zMax;
- return self;
- }
-
- - init
- {
- [super init];
- radius = 1.;
- zMax = 1.;
- zMin = -1.;
- thetaMax = 360.;
- [self calcBoundingBox];
- return self;
- }
-
- - setRadius:(RtFloat *) aRad
- {
- [super setRadius:aRad];
- [self calcBoundingBox];
- return self;
- }
-
- - setZMax:(RtFloat *)z;
- {
- [super setZMax:z];
- [self calcBoundingBox];
- return self;
- }
-
- - setZMin:(RtFloat *)z;
- {
- [super setZMin:z];
- [self calcBoundingBox];
- return self;
- }
-
- /* SolidSphere: create a closed sphere */
- void
- SolidSphere(rad, zmin, zmax)
- RtFloat rad, zmin, zmax;
- {
- RiSolidBegin(RI_PRIMITIVE);
-
- RiSphere(rad, zmin, zmax, 360.0, RI_NULL);
-
- if(fabs(zmax) < rad) /* The top is chopped off */
- RiDisk(zmax, sqrt(rad*rad - zmax*zmax), 360.0, RI_NULL);
-
- if(fabs(zmin) < rad) /* The bottom is chopped off */
- RiDisk(zmin, sqrt(rad*rad - zmin*zmin), 360.0, RI_NULL);
-
- RiSolidEnd();
- }
-
- /*
- * SolidCylinder() makes a solid cylinder of the given radius, extending
- * from zmin to zmax along the z axis.
- */
- void
- SolidCylinder(rad, zmin, zmax)
- float rad, zmin, zmax;
- {
- RiSolidBegin(RI_PRIMITIVE);
-
- RiCylinder(rad, zmin, zmax, 360.0, RI_NULL);
-
- RiDisk(zmax, rad, 360.0, RI_NULL); /* Close the top */
- RiDisk(zmin, rad, 360.0, RI_NULL); /* Close the bottom */
-
- RiSolidEnd();
- }
-
-
- /* SolidHemisphere: create a solid hemisphere from a sphere and a cylinder*/
- void
- SolidHemisphere(rad, zmin, zmax)
- float rad, zmin, zmax;
- {
- RiSolidBegin(RI_INTERSECTION);
- SolidSphere(rad, zmin, zmax);
- /*
- * A cylinder is defined with the same radius as the sphere and
- * rotated so that its bottom bisects the sphere in the x/z plane.
- */
- RiRotate(90.0, 1.0, 0.0, 0.0);
- /* Rotate the cylinder 90 degrees in x */
- SolidCylinder(rad, 0.0, rad);
- RiSolidEnd(); /* intersection */
- }
-
- void
- SolidWedge(rad, zmin, zmax, thetamax)
- float rad, zmin, zmax, thetamax;
- {
- if (thetamax == 180.0) {
- SolidHemisphere(rad, zmin, zmax);
- } else if (thetamax == 360.0) {
- SolidSphere(rad, zmin, zmax);
- } else if (thetamax < 180.0) {
- RiSolidBegin(RI_INTERSECTION);
- SolidHemisphere(rad, zmin, zmax);
- RiRotate(thetamax-180.0, 0.0, 0.0, 1.0);
- SolidHemisphere(rad, zmin, zmax);
- RiSolidEnd();
- } else if (thetamax < 360.0) {
- RiSolidBegin(RI_UNION);
- SolidHemisphere(rad, zmin, zmax);
- RiRotate(thetamax, 0.0, 0.0, 1.0);
- SolidHemisphere(rad, zmin, zmax);
- RiSolidEnd();
- }
- }
-
- - doRenderSelf: (Camera *) camera
- {
- if(![super doRenderSelf:camera]) return nil;
-
- if (shFlags.isSolid)
- SolidWedge(radius,zMin,zMax,thetaMax);
- else
- RiSphere(radius,zMin,zMax,thetaMax,RI_NULL);
- return self;
- }
- @end
-